/*
 * Design_Assignment_6.c
 *
 * Created: 4/16/2014 11:20:04 AM
 *  Author: Jared
 *This program will control the speed of a stepper motor, as well as the position of a servo motor 
 *using a potentiometer connected to PC0 of the Atmega328P.
 *
 */ 

#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>


void ServoMotor(void); void StepMotor(void); void ADCConvert(void);

int main(void)
{
    while(1)
    {
		DDRB = 0xFF;
		DDRD = 0xFF;												// Ports B and D as output
		DDRC = 0;													// Port C as input
		PORTD=0xFF;
		
		ADCConvert();
		StepMotor();
		ServoMotor();	
    }
}

void StepMotor(void){
	while (1)
	{
		if((PINC&0x01) == 0)										// Check PC0, switch directions
		{
			PORTB = 0x66;											// Rotate Counter-Clockwise
			_delay_ms(100);
			PORTB = 0xCC;
			_delay_ms(100);
			PORTB = 0x99;
			_delay_ms(100);			
			PORTB = 0x33;
			_delay_ms(100);							
		}
		else
		{															// Rotate Clockwise		
			PORTB = 0x66;
			_delay_ms(100);
			PORTB = 0x33;
			_delay_ms(100);
			PORTB = 0x99;
			_delay_ms(100);
			PORTB = 0xCC;
			_delay_ms(100);			
		}
	}
	
}

void ServoMotor(void){
	 ICR1=20000;													//ICR1=20000 defines 50Hz PWM,   TOP=ICR1;
	 TCCR1A|=(0<<COM1A0)|(1<<COM1A1)|(0<<COM1B0)|(0<<COM1B1)|		//Output compare OC1A 8 bit non inverted PWM
	 (0<<FOC1A)|(0<<FOC1B)|(1<<WGM11)|(0<<WGM10);
	 TCCR1B|=(0<<ICNC1)|(0<<ICES1)|(1<<WGM13)|(1<<WGM12)|			//Clear OC1A on Compare Match, set OC1A at TOP
	 (0<<CS12)|(1<<CS11)|(0<<CS10);									//start timer with prescaler 8

	 for (;;)
	 {
		if(bit_is_clear(PIND, 0))
		{
			//increase duty cycle
			OCR1A+=10;
			loop_until_bit_is_set(PIND, 0);
		}
		if(bit_is_clear(PIND, 1))
		{
			//decease duty cycle
			OCR1A-=10;
			loop_until_bit_is_set(PIND, 1);
		}
	 }
}

void ADCConvert(void){	
	ADCSRA |= (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1);		// ADC enable, ck/64
	ADMUX |= (1 << REFS0) | (1 << REFS1);						// 2.56 Vref, ADC0 single-ended
	
	ADCSRA |= (1 << ADSC);										// Start conversion
	while ((ADCSRA & (1 << ADIF)) == 0);						// Wait for end of conversion
		PORTD = ADCL;
		PORTB = ADCH;
}